home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 10
/
AACD 10.iso
/
AACD
/
Online
/
SpeakFreely
/
src
/
lpc10
/
bsynz.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-05-18
|
3KB
|
147 lines
/******************************************************************
*
* BSYNZ Version 49
*
******************************************************************
*
* Synthesize One Pitch Epoch
*
* Inputs:
* COEF - Predictor coefficients
* IP - Pitch period (number of samples to synthesize)
* IV - Voicing for the current epoch
* RMS - Energy for the current epoch
* ORDER - Synthesizer filter order (number of PC's)
* RATIO - Energy slope for plosives
* G2PASS- Sharpening factor for 2 pass synthesis
* Outputs:
* SOUT - Synthesized speech
*/
#include "config.ch"
/*#include "common.h"*/
#include "lpcdefs.h"
#include <math.h>
/*
#define MESCL 1.0
#define PESCL 1.0
*/
float kexc[25]={
8,-16,26,-48,86,-162,294,-502,718,-728,
184,672,-610,-672,184,728,718,502,294,162,
86,48,26,16,8
};
extern float exc[MAXPIT+MAXORD], exc2[MAXPIT+MAXORD];
bsynz( coef, ip, iv, sout, rms, ratio, g2pass )
int ip, iv;
float coef[], sout[], g2pass, rms, ratio;
{
int px;
static int ipo=0;
int i, j, k;
float noise[MAXPIT+MAXORD];
float lpi0, hpi0;
float a0=.125, a1=.75, a2=.125/*, a3=0*/, b0=-.125, b1=.25, b2=-.125/*, b3=0*/;
float pulse, sscale, xssq, sum, ssq, gain;
float xy;
static float rmso=0.0, lpi1=0.0, lpi2=0.0, /*lpi3,*/ hpi1=0.0, hpi2=0.0/*, hpi3*/;
/* Calculate history scale factor XY and scale filter state */
xy = mmin((rmso/(rms+.000001)), 8.0);
rmso = rms;
for(i=0;i<ORDER;i++)
exc2[i] = exc2[ipo+i]*xy;
ipo = ip;
if(iv==0) {
/* Generate white noise for unvoiced */
for(i=0;i<ip;i++)
/*exc[ORDER+i] = (int)(Rrandom() * 0.015625);*/
exc[ORDER+i] = Rrandom() >>6;
/* Impulse doublet excitation for plosives */
px = ((Rrandom()+32768)*(ip-1)>>16) + ORDER + 1;
/*pulse = PESCL*(ratio*.25)*342;*/
pulse = ratio*85.5;
if(pulse>2000) pulse = 2000;
exc[px-1] += pulse;
exc[px] -= pulse;
/* Load voiced excitation */
}
else {
/*sscale = sqrt((float)ip)/6.928;*/
sscale = sqrt((float)ip)*0.144341801;
for(i=0;i<ip;i++) {
exc[ORDER+i] = 0.;
if(i<=25) exc[ORDER+i] = sscale*kexc[i];
lpi0 = exc[ORDER+i];
exc[ORDER+i] = a0*exc[ORDER+i] + a1*lpi1 + a2*lpi2 /*+ a3*lpi3*/;
/*lpi3 = lpi2;*/
lpi2 = lpi1;
lpi1 = lpi0;
}
for(i=0;i<ip;i++) {
/*noise[ORDER+i] = MESCL * (int)(Rrandom() * 0.015625);*/
noise[ORDER+i] = Rrandom() >>6;
hpi0 = noise[ORDER+i];
noise[ORDER+i] = b0*noise[ORDER+i] + b1*hpi1 + b2*hpi2 /*+ b3*hpi3*/;
/*hpi3 = hpi2; */
hpi2 = hpi1;
hpi1 = hpi0;
}
for(i=0;i<ip;i++)
exc[ORDER+i] += noise[ORDER+i];
}
/* Synthesis filters:
* Modify the excitation with all-zero filter 1 + G*SUM */
xssq = 0;
for(i=0;i<ip;i++) {
k = ORDER + i;
sum = 0.;
for(j=0;j<ORDER;j++)
sum += coef[j]*exc[k-j-1];
sum *= g2pass;
exc2[k] = sum + exc[k];
}
/* Synthesize using the all pole filter 1 / (1 - SUM) */
for(i=0;i<ip;i++) {
k = ORDER + i;
sum = 0.;
for(j=0;j<ORDER;j++)
sum += coef[j]*exc2[k-j-1];
exc2[k] += sum;
xssq = xssq + exc2[k]*exc2[k];
}
/* Save filter history for next epoch */
for(i=0;i<ORDER;i++) {
exc[i] = exc[ip+i];
exc2[i] = exc2[ip+i];
}
/* Apply gain to match RMS */
ssq = rms*rms*ip;
gain = sqrt(ssq/xssq);
for(i=0;i<ip;i++)
sout[i] = gain*exc2[ORDER+i];
}